<template>
  <div class="yz-input">
    <div class="form-inline" style="padding: 0;display: block">
      <q-input  v-if="inputType === 'input'"
                v-model="inputData"
                dense
                emit-value
                map-options
                :disable="isDisable"
                :rules="rulesData"
                :maxlength="maxlength"
                :placeholder="placeholder"
                ref="yzInput"
                outlined>
        <template v-slot:before>
          <label class="text-right name form-name label-width text-ellipsis" :class="[ellipsis ? 'text-ellipsis' : '']"  v-if="title" :style ="setWidth">
            <span class="text-red" v-if="rules.length > 0 && isRule">*</span><span>{{title}}: <q-tooltip v-if="ellipsis">{{title}}</q-tooltip></span>
            <q-icon name="iconfont icontubiao-72" class="font-18 text-grey" style="margin-left: 5px" v-if="tips !== ''">
              <q-tooltip>{{tips}}</q-tooltip>
            </q-icon>
          </label>
        </template>
        <template v-slot:after>
          <slot name="after"></slot>
        </template>
        <template v-slot:hint>
          <slot name="hint"></slot>
        </template>
      </q-input>
      <q-select v-else-if="inputType === 'select'"
                v-model="inputData"
                :options="options"
                dense
                options-dense
                lazy-rules
                class="form-select"
                :disable="isDisable"
                @input="onSelect"
                :multiple="multiple"
                emit-value
                ref="yzInput"
                map-options
                :placeholder="placeholder"
                outlined
                :rules="rulesData">
        <template v-slot:no-option>
          <div class="no-option" />
        </template>
        <template v-slot:after>
          <slot name="after"></slot>
        </template>
        <template v-slot:before>
          <label class="text-right name form-name label-width"  v-if="title" :style="{ width }">
            <span class="text-red" v-if="rules.length > 0 && isRule">*</span> <span>{{title}}:</span>
            <q-icon name="iconfont icontubiao-72" class="font-18 text-grey" style="margin-left: 5px" v-if="tips !== ''">
              <q-tooltip>{{tips}}</q-tooltip>
            </q-icon>
          </label>
        </template>
      </q-select>
      <q-select v-else-if="inputType === 'filterSelect'"
                v-model="inputData"
                :options="selectOptions"
                dense
                options-dense
                use-input
                class="form-select"
                @filter="filterFn"
                input-debounce="300"
                type="text"
                clearable
                :disable="isDisable"
                @input="onSelect"
                emit-value
                ref="yzInput"
                map-options
                :placeholder="placeholder"
                outlined
                :rules="rulesData">
        <template v-slot:no-option>
          <div class="no-option" />
        </template>
      </q-select>
      <div v-else-if="inputType === 'date'">
        <div class="form-item">
          <span class="text-red font-size-16" v-if="rules.length > 0 && isRule">*</span><span class="name form-name" style="padding-right: 6px" v-if="title">{{title}}:</span>
          <date-picker
            v-model="inputData"
            :type="dateType"
            :valueType="valueType"
            :clearable="clearable"
            :editable="false"
            :range="isRange"
            ref="yzInput"
            :disabled-date="disabledType"
            @change="getDateRange"
            :style=" { width : isRange ? '240px' : '180px'}"
            :format="format"
            :placeholder="placeholder"/>
        </div>
      </div>
      <q-input  v-if="inputType === 'textarea'"
                class="textarea"
                v-model="inputData"
                type="textarea"
                :counter="!!maxlength"
                :autogrow="autogrow"
                :disable="isDisable"
                ref="yzInput"
                :rules="rulesData"
                :maxlength="maxlength"
                :placeholder="placeholder"
                outlined>
        <template v-slot:before>
          <label class="text-right name form-name label-width"  v-if="title" :style="{ width }">
            <span class="text-red" v-if="rules.length > 0 && isRule">*</span><span>{{title}}:</span>
          </label>
        </template>
      </q-input>
    </div>
  </div>
</template>

<script>
import _ from 'lodash'
import moment from 'moment'
import ruleList from './rules'
export default {
  name: 'yz-input',
  props: {
    value: [Array, String, Number, Date, Object],
    inputType: {
      type: String,
      default: 'input'
    },
    width: String,
    options: Array,
    // 自定义校验规则
    hintRule: Array,
    rules: { // 校验规则
      type: Array,
      default () {
        return []
      }
    },
    maxlength: Number,
    title: { // 校验规则
      type: String,
      default: ''
    },
    hint: { // 占位符
      type: String,
      default: ''
    },
    isRule: {
      type: Boolean,
      default: true
    },
    autogrow: {
      type: Boolean,
      default: true
    },
    tips: { // 提示
      type: String,
      default: ''
    },
    isDisable: Boolean,
    // 日期组件
    dateType: {
      type: String,
      default: 'date' // date, week, month
    },
    valueType: {
      type: String,
      default: 'date'
    },
    // 是否需要时间提示
    isTip: {
      type: Boolean,
      default: false
    },
    // 是否手动输入形式
    dateFormat: {
      type: String,
      default: ''
    },
    // 是否是范围
    isRange: {
      type: Boolean,
      default: true
    },
    // 是否多选日期
    multiple: {
      type: Boolean,
      default: false
    },
    clearable: { // 是否可清空
      type: Boolean,
      default: false
    },
    refVal: {
      type: String,
      default: ''
    },
    // 禁用什么时候的日期
    disabledType: Function,
    // 增加下拉选情况下的提示，
    // 应用场景： 不让全部选择。
    disSelect: {
      type: Object,
      default () {
        return {
          tip: '', // 提示
          count: 1, // 不让选择的个数
          isSelect: false // 是否需要校验提示
        }
      }
    },
    ellipsis: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      inputData: null,
      dateList: {
        date: 'YYYY-MM-DD',
        week: 'YYYY-MM-DD',
        month: 'YYYY-MM'
      },
      dateTypeOption: [
        {
          value: 'date',
          msg: '日期范围最大不可超过30天',
          interval: 30
        },
        {
          value: 'week',
          msg: '日期范围最大不可超过10周',
          interval: 10
        },
        {
          value: 'month',
          msg: '日期范围最大不可超过24月',
          interval: 24
        }
      ],
      selectOptions: []
    }
  },
  watch: {
    value: {
      handler (val) {
        this.inputData = val
      },
      deep: true,
      immediate: true
    },
    inputData: {
      deep: true,
      handler () {
        this.$emit('input', this.inputData)
      }
    },
    options: {
      immediate: true,
      deep: true,
      handler () {
        if (this.inputType === 'filterSelect') {
          this.selectOptions = _.cloneDeep(this.options)
        }
      }
    }
  },
  computed: {
    setWidth () {
      return this.width ? { width: this.width } : {}
    },
    // 日期格式提示
    format () {
      return this.dateFormat || _.get(this.dateList, this.dateType, false)
    },
    // 占位符
    placeholder () {
      let tip = this.inputType === 'input' || this.inputType === 'textarea' ? '请输入' : '请选择'
      return this.hint ? this.hint : this.title ? `${tip}${this.title}` : ''
    },
    // rule 校验
    rulesData () {
      const member = this.rules.reduce((arr, item) => {
        arr.push(ruleList[item])
        return arr
      }, [])
      return [...member, ...(this.hintRule || [])]
    }
  },
  methods: {
    validateVal () {
      this.$refs.yzInput.validate()
    },
    onSelect (val) {
      const { tip, isSelect } = this.disSelect
      if (val?.length === this.options.length && isSelect) {
        this.$message.warning(tip)
        this.inputData = _.initial(val)
        val = _.initial(val)
      }
      this.$emit('on-select', val)
    },
    // 日区间 val范围界限
    _isLtDay (val) {
      const member = Math.abs(moment(this.inputData[0]).diff(moment(this.inputData[1]),
        this.dateType === 'date' ? 'days' : this.dateType))
      return member > val
    },
    // 超过给出日期范围提示, 并且清空时间范围,为当天
    getDateRange () {
      if (!this.isTip) return
      const member = _.find(this.dateTypeOption, { value: this.dateType })
      if (this._isLtDay(_.get(member, 'interval', 60))) {
        this.$message.warning(_.get(member, 'msg', ''))
        this.inputData = [new Date(), new Date()]
      }
    },
    filterFn (val, update) {
      if (val === '') {
        update(() => {
          this.selectOptions = this.options
        })
        return
      }
      update(() => {
        // 根据label进行前端过滤
        const needle = val.trim()
        this.selectOptions = this.options.filter(v => v.label.indexOf(needle) > -1)
        if (this.selectOptions.findIndex(item => item.value === this.inputData) === -1) {
          this.inputData = null
        }
      })
    }
  },
  mounted () {

  }
}
</script>

<style scoped lang="stylus">
  >>>.textarea .q-field__control {
    min-height: 72px !important;
  }
  .form-select >>>span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
</style>
